﻿// -----------------------------------------------------------------------
// <copyright file="Program.cs" company="FastNET Services">
//     Copyright (c) 2008-2009. All Rights Reserved.
// </copyright>
// <license>
//     GPLv2
// </license>
// <warranty>
//     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
//     BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
//     DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// </warranty>
// -----------------------------------------------------------------------
#region Usings

using System;
using System.ServiceProcess;
using GateShift.Servers.GameServer.Core;
using GateShift.Servers.GameServer.HelperClasses;

#endregion

namespace GateShift.Servers.GameServer
{
    /// <summary>
    /// Entrance class for GateShiftServer
    /// </summary>
    public static class Program
    {
        #region Private Variables

        private static readonly GateShiftService _service;

        #endregion

        #region CTor/DTor

        /// <summary>
        /// Initializes static members of the Program class
        /// </summary>
        static Program()
        {
            _service = new GateShiftService();
        }

        #endregion

        #region Application Initialization

        /// <summary>
        /// Entrance method for GateShiftServer
        /// </summary>
        /// <param name="args">string array of arguments passed from the command line</param>
        /// <returns>int error code. 0 for success</returns>
        public static int Main(string[] args)
        {
            // If we have any arguments, lets go try to parse them and apply them
            foreach (ArgumentAction item in ArgumentHelper.ProcessArguments(args))
            {
                switch (item)
                {
                    case ArgumentAction.InvalidArgument:
                        return -1;
                    case ArgumentAction.PrintHelp:
                        ArgumentHelper.PrintHelp();
                        return 0;
                    case ArgumentAction.ConsoleMode:
                        SystemGlobals.ConsoleMode = true;
                        break;
                }
            }

            // Set up common application mode settings
            ApplicationStart();

            // Look at the run mode to determine whether or not the application should run with a console
            if (!SystemGlobals.ConsoleMode)
            {
                RunService();
            }
            else
            {
                RunConsole();
            }

            return 0;
        }

        /// <summary>
        /// Runs the application as a Windows Service
        /// </summary>
        private static void RunService()
        {
            ServiceBase.Run(_service);
        }

        /// <summary>
        /// Runs the application as a Console Application
        /// </summary>
        private static void RunConsole()
        {
            _service.Start();

            System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
        }

        #endregion

        #region Application Management

        /// <summary>
        /// Attaches resources for global application management
        /// </summary>
        private static void ApplicationStart()
        {
            AppDomain.CurrentDomain.UnhandledException += AppDomain_UnhandledException;
            AppDomain.CurrentDomain.ProcessExit += ApplicationExit;
        }

        /// <summary>
        /// Handles exiting of the application
        /// </summary>
        /// <param name="sender">AppDomain calling this method</param>
        /// <param name="e">Empty EventArgs</param>
        private static void ApplicationExit(object sender, EventArgs e)
        {
            if (SystemGlobals.ConsoleMode && _service.IsAlive)
            {
                _service.Stop();
            }

            Environment.ExitCode = 0;
        }

        /// <summary>
        /// Handles any unhandles exceptions for the application
        /// </summary>
        /// <param name="sender">AppDomain calling this method</param>
        /// <param name="e">UnhandledExceptionEventArgs with information about the event</param>
        private static void AppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
        }

        #endregion
    }
}